/*
 ============================================================================
 Name        : compart.c
 Author      : anonymous
 Version     :
 Copyright   : 21212121
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

#include "configurar.h"
#include "structs.h"
#include "Conectar.h"
#include "menu.h"
#include "arquivo.h"
#include "busca.h"


//Vizinho v1, v2;

//int contadorRandom;

int main(void) {

    CriarTabelaVizinho(&tabela_vizinhos);
    criatabela(&registrobusca);
  //  preenche(&tabelabusca);
    listararquivos(&tabelaarquivo);
    criartabelabusca(&tabelabusca);
  //  printtabelaarquivo();
    menu();

    /*
     strcpy(v1.Ip, "199.0.0.12");
     v1.PortaTcp = 5001;
     v1.PortaUdp = 5006;

     for (contadorRandom = 0; contadorRandom < 4; contadorRandom++) {
     strcpy(v2.Ip, "199.0.0.233");
     v2.PortaTcp = contadorRandom;
     v2.PortaUdp = contadorRandom + 1;
     AdicionarVizinho(tabela_vizinhos, &v2);
     }

     strcpy(v2.Ip, "99.0.0.233");
     v2.PortaTcp = 398;
     v2.PortaUdp = 399;

     AdicionarVizinho(tabela_vizinhos, &v1);
     //AdicionarVizinho(tabela_vizinhos, &v2);

     RemoverVizinho(tabela_vizinhos, &v2);
     ////////////////////////*/

    return EXIT_SUCCESS;
}

/*
 // variaveis globais //
 #define BACKLOG 10


 int PortaEscuta, retThreadConTest, retThreadConecHand;

 pthread_t ThreadConTest, ThreadConecHand;



 typedef struct {
 int Socket;
 struct sockaddr_in ipremoto;
 char dados[16384];
 } SendPack;

 SendPack buffertst;

 typedef struct {
 int Socket;
 struct sockaddr_in ipremoto;
 char dados[16384];
 } SocketIp;

 SendPack buffertst;


 ///////////////////////////
 // manipula uma conexao
 // com um cliente
 // transmite dados
 //////////////////////////
 void *SendConTeste(void * arg) {
 int numbytes;
 char msg_recv[16] = "arquivo";
 FILE *arquivomandar;
 int ciclosenvio = 0;

 while (1) {
 if (1) {
 bzero(&(buffertst.dados), 16384);
 sprintf(buffertst.dados,
 "\n envie \"arquivo\" para receber o arquivo!");
 send(buffertst.Socket, buffertst.dados, 58 * sizeof(char), 0);

 numbytes = recv(buffertst.Socket, buffertst.dados, 16, 0);

 buffertst.dados[numbytes] = '\0';
 printf("Recebido: %s", buffertst.dados);

 if (!strcmp(buffertst.dados, msg_recv)) {
 puts("abrir arquivo");
 arquivomandar = fopen("arquivo", "r");

 fseek(arquivomandar, 0, SEEK_END);
 numbytes = ftell(arquivomandar);
 fseek(arquivomandar, 0, SEEK_SET);

 printf("\nenviando arquivo. %d bytes no total.\n", numbytes);
 ciclosenvio = numbytes / 16384;
 // sei que o arquivo tem menos de 16kb, mas para arquivos
 // maiores é preciso colocar um loop de envio aqui e quebrar
 // "ciclosenvio" vezes o arquivo + 1 para enviar. o ultimo envio é de
 // resto = numbytes % 16384.
 // é preciso informar o outro lado tambem sobre o tamanho do arquivo.

 bzero(&(buffertst.dados), 16384);
 fread(&buffertst.dados, numbytes, 1, arquivomandar);
 send(buffertst.Socket, buffertst.dados, numbytes, 0);
 puts("\n enviado!");
 fclose(arquivomandar);
 }

 }
 }
 return NULL;
 }

 void *ConexaoHandler(void * arg) {

 return NULL;
 }

 // /////////////////////////
 // apenas desacopla o código
 // de criação de thread
 // /////////////////////////

 void CriarConexao(int socketremoto, struct sockaddr_in ipremoto) {

 //buffertst.Socket = socketremoto;
 //buffertst.ipremoto = ipremoto;

 //retThreadConTest = pthread_create(&ThreadConTest, NULL, SendConTeste,
 //		(void*) NULL);
 retThreadConecHand = pthread_create(&ThreadConecHand, NULL, ConexaoHandler,
 (void*) NULL);
 return;
 }

 // /////////////////////
 //  thread de servidor que fica
 //  ativa recebendo conexões
 //  transfere o socket criado para
 //  outra thread: conexaohandler();
 // /////////////////////

 void * Servidor(void *arg) {

 int SocketEscuta, SocketNovaConexao;
 struct sockaddr_in ip_local;
 struct sockaddr_in ip_remoto;
 unsigned int tamanho;

 if ((SocketEscuta = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 perror("socket");
 exit(1);
 }

 PortaEscuta = 5001;

 ip_local.sin_family = AF_INET;
 ip_local.sin_port = htons(PortaEscuta);
 ip_local.sin_addr.s_addr = INADDR_ANY;
 bzero(&(ip_local.sin_zero), 8);

 if (bind(SocketEscuta, (struct sockaddr *) &ip_local,
 sizeof(struct sockaddr)) == -1) {
 perror("bind");
 exit(1);
 }

 if (listen(SocketEscuta, BACKLOG) < 0) {
 perror("listen");
 exit(1);
 }
 puts("Servidor criado e na escuta;");
 for (;;) {
 tamanho = sizeof(struct sockaddr_in);
 if ((SocketNovaConexao = accept(SocketEscuta,
 (struct sockaddr *) &ip_remoto, &tamanho)) < 0) {
 perror("accept");
 continue;
 }
 printf("Servidor: chegando conexão de %s\n", inet_ntoa(
 ip_remoto.sin_addr));

 CriarConexao(SocketNovaConexao, ip_remoto);
 }

 return (NULL);
 }

 void * Cliente(void *arg) {

 int gotchar;

 int SocketLocal, numbytes, porta;
 char buf[16384], ip[16];
 struct sockaddr_in servidor;

 FILE *arquivoreceber;

 porta = 5001;

 puts("cliente criado");
 while (1) {
 puts("Deseja receber arquivo? s/n ");
 gotchar = getchar();
 if (gotchar == 's') {
 // começa a pedir e receber arquivo
 if ((SocketLocal = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
 perror("socket");
 exit(1);
 }

 puts("\n digite o ip: ");
 scanf("%s", ip);
 //puts("\n digite a porta: ");
 //scanf("%d", &ip);
 servidor.sin_family = AF_INET;
 servidor.sin_port = htons(porta);
 servidor.sin_addr.s_addr = inet_addr(ip);
 bzero(&(servidor.sin_zero), 8);

 if (connect(SocketLocal, (struct sockaddr *) &servidor,
 sizeof(servidor)) == -1) {
 close(SocketLocal);
 }
 if ((numbytes = recv(SocketLocal, buf, 16384, 0)) == -1) {
 perror("recv");
 exit(1);
 }

 buf[numbytes] = '\0';
 printf("Recebido: %s", buf);
 /////////////////////////////////////////////////////////////////////////
 if (send(SocketLocal, "arquivo", 8, 0) == -1) {
 perror("send");
 close(SocketLocal);
 exit(0);
 }
 if ((numbytes = recv(SocketLocal, buf, 16384, 0)) == -1) {
 perror("recv");
 exit(1);
 }
 arquivoreceber = fopen("ArquivoRecebido", "w");
 fwrite(buf, numbytes, 1, arquivoreceber);
 fclose(arquivoreceber);
 close(SocketLocal);
 }
 }
 return (NULL);
 }

 int IniciarServidor() {
 int retThreadServer;
 pthread_t ThreadServer;

 retThreadServer = pthread_create(&ThreadServer, NULL, Servidor,
 (void*) NULL);
 pthread_join(ThreadServer, NULL);
 return (0);
 }

 int IniciarCliente() {
 int retThreadCliente;
 pthread_t ThreadCliente;

 puts("Vou criar uma thread de cliente");
 retThreadCliente = pthread_create(&ThreadCliente, NULL, Cliente,
 (void*) NULL);
 pthread_join(ThreadCliente, NULL);
 return (0);
 }

 int main(void) {

 char tecla;

 puts("Criar Servidor? s/n ");

 tecla = getchar();
 if (tecla == 's') {
 IniciarServidor();
 }
 IniciarCliente();

 return EXIT_SUCCESS;
 }
 */
